package com.tianji.promotion.utils;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

import static com.tianji.promotion.utils.MyLockType.*;

@Component
public class MyLockFactory {

    private final Map<MyLockType, Function<String, RLock>> lockHandlers;

    public MyLockFactory(RedissonClient redissonClient) {
        this.lockHandlers = new EnumMap<>(MyLockType.class);
        this.lockHandlers.put(RE_ENTRANT_LOCK, redissonClient::getLock);   // ===>  this.lockHandlers.put(RE_ENTRANT_LOCK, name -> redissonClient.getLock(name));
        this.lockHandlers.put(FAIR_LOCK, redissonClient::getFairLock);  // ===>  this.lockHandlers.put(FAIR_LOCK, name -> redissonClient.getFairLock(name));
        this.lockHandlers.put(READ_LOCK, name -> redissonClient.getReadWriteLock(name).readLock());
        this.lockHandlers.put(WRITE_LOCK, name -> redissonClient.getReadWriteLock(name).writeLock());
    }

    public RLock getLock(MyLockType lockType, String name) {
        return lockHandlers.get(lockType).apply(name);
    }

    // ===================================================================================

    @FunctionalInterface
    interface MathOperation{
        int apply(int a,int b);
    }

    private static  Map<String, MathOperation> mathOperationMap;
    static{
        mathOperationMap = new HashMap<>();
        mathOperationMap.put("add", (a,b) -> a + b);
        mathOperationMap.put("sub", (a,b) -> a - b);
        mathOperationMap.put("mul", (a,b) -> a * b);
        mathOperationMap.put("div", (a,b) -> a / b);
    }

    public static int compute(String type,int a,int b){
        return mathOperationMap.get(type).apply(a,b);
    }

    public static void main(String[] args) {
        System.out.println(compute("add",5,7));
    }


    /* public static int compute(String type,int a,int b){
        switch (type){
            case "add":
                return a+b;
            case "sub":
                return a-b;
            case "mul":
                return a*b;
            case "div":
                return a/b;
            default:
                return 0;
        }
    }*/

}